package br.com.light.retorno.cancelamento.ws;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.DOMOutputter;

import com.sap.aii.mapping.api.StreamTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;

public class MappingRetornoCancelamentoWStoSP implements StreamTransformation{
	
//	private AbstractTrace //trace = null;
	private Map mapTrace = null;

	/**
	 * @param args
	 * @throws FileNotFoundException 
	 * @throws StreamTransformationException 
	 */
	public static void main(String[] args) throws FileNotFoundException, StreamTransformationException {
		File file = new File("D:/documentos/Complex/Light/RetornoCancelamentoWS_1.xml");
		InputStream in = new FileInputStream(file);
			
		File fileOut = new File("D:/documentos/Complex/Light/RetornoCancelamentoSP_1.xml");
		OutputStream out = new FileOutputStream(fileOut);
		
		new MappingRetornoCancelamentoWStoSP().execute(in, out);
	}

	public void execute(InputStream in, OutputStream out)
			throws StreamTransformationException {
		
		//trace = (AbstractTrace) mapTrace.get(StreamTransformationConstants.MAPPING_TRACE);
	
		try {
			
			Reader reader = new BufferedReader(new InputStreamReader(in, "ISO-8859-1"));
		    StringBuffer content = new StringBuffer();
		    char[] buffer = new char[1024];
		    int n;
		     
		    while ( ( n = reader.read(buffer)) != -1 ) {
		        content.append(buffer,0,n);
		    }
		    
		    String retorno = content.toString();
		    
		    //trace.addInfo("3 - Retorno do WebService da Prefeitura antes do tratamento de caracteres: "+ retorno);
		    
		    int x = retorno.indexOf("<RetornoXML>");
		    //trace.addInfo("4 - Posicao do Inicio do Retorno: "+x);
		    int j = retorno.indexOf("</RetornoXML>");
		    //trace.addInfo("5 - Posicao do Fim  do Retorno: "+j);
			
			String xmlPI = retorno.substring(x+12, j).trim();
			
			//trace.addInfo("5.1 - XML Editado: "+xmlPI);
			
			String nfeProcStr = xmlPI.replaceAll( "&#62;", ">" ).
					  replaceAll("&#60;", "<" );
		    
		    //trace.addInfo("6 - XML Editado depois do tratamento de caracteres: "+ nfeProcStr);
			
			int k = nfeProcStr.indexOf("?>");
			String xmlFinal = nfeProcStr.substring(k+2);
			
			InputStream inWS = new ByteArrayInputStream(xmlFinal.getBytes());
			
			Element header = new Element("RetornoCancelamentoNFe", "ns1", "http://www.prefeitura.sp.gov.br/nfe");
			Element cabecalho = new Element("Cabecalho");
			cabecalho.setAttribute("Versao", "1");
			header.addContent(cabecalho);
			
			SAXBuilder builder = new SAXBuilder();
			Document doc = builder.build(inWS);
			Element root = doc.getRootElement();
			List elements = root.getChildren();
			Iterator iter = elements.iterator();
				
				while (iter.hasNext()) {
					Element elem = (Element) iter.next();
					
					if("Cabecalho".equals(elem.getName())){
						Element sucesso = new Element("Sucesso");
						cabecalho.addContent(sucesso);
						String sucessoIn = elem.getChildText("Sucesso");
						sucesso.setText(sucessoIn);
					}
					
					if("Alerta".equals(elem.getName())){
						Element alerta = new Element("Alerta");
						header.addContent(alerta);
						List listAlertaChilds = elem.getChildren();
						Iterator alertaChildIter = listAlertaChilds.iterator();
						while(alertaChildIter.hasNext()){
							
							Element alertaChildElement = (Element)alertaChildIter.next();
							
							if("Codigo".equals(alertaChildElement.getName())){
								Element codigoAlerta = new Element("Codigo");
								alerta.addContent(codigoAlerta);
								String codigoIn = elem.getChildText("Codigo", elem.getNamespace());
								codigoAlerta.setText(codigoIn);
								continue;
							}	
							if("Descricao".equals(alertaChildElement.getName())){
								Element descricao = new Element("Descricao");
								alerta.addContent(descricao);
								String descricaoIn = elem.getChildText("Descricao", elem.getNamespace());
								descricao.setText(descricaoIn);
								continue;
							}	
							if("ChaveRPS".equals(alertaChildElement.getName())){
								Element chaveRPSAlerta = new Element("ChaveRPS");
								alerta.addContent(chaveRPSAlerta);
								
								Element inscPrestAlerta = new Element("IscricaoPrestador");
								chaveRPSAlerta.addContent(inscPrestAlerta);
								String inscPrestRPSIn = alertaChildElement.getChildText("InscricaoPrestador", alertaChildElement.getNamespace());
								inscPrestAlerta.setText(inscPrestRPSIn);
								
								Element serieRPSAlerta = new Element("SerieRPS");
								chaveRPSAlerta.addContent(serieRPSAlerta);
								String serieRPSIn = alertaChildElement.getChildText("SerieRPS", alertaChildElement.getNamespace());
								serieRPSAlerta.setText(serieRPSIn);
								
								Element numRPSAlerta = new Element("NumeroRPS");
								chaveRPSAlerta.addContent(numRPSAlerta);
								String numRPSIn = alertaChildElement.getChildText("NumeroRPS", alertaChildElement.getNamespace());
								numRPSAlerta.setText(numRPSIn);
								continue;
								
							}
							if("ChaveNFe".equals(alertaChildElement.getName())){
								Element chaveNFEAlerta = new Element("ChaveNFe");
								alerta.addContent(chaveNFEAlerta);
								

								Element inscPrestChaveNfeAlerta = new Element("InscricaoPrestador");
								chaveNFEAlerta.addContent(inscPrestChaveNfeAlerta);
								String inscPrestNfeIn = alertaChildElement.getChildText("InscricaoPrestador", alertaChildElement.getNamespace());
								inscPrestChaveNfeAlerta.setText(inscPrestNfeIn);
								

								Element numNfeAlerta = new Element("NumeroNfe");
								chaveNFEAlerta.addContent(numNfeAlerta);
								String numNfeIn = alertaChildElement.getChildText("NumeroNFe",alertaChildElement.getNamespace());
								numNfeAlerta.setText(numNfeIn);
								
								Element codVerifAlerta = new Element("CodigoVerificacao");
								chaveNFEAlerta.addContent(codVerifAlerta);
								String codVerifNfeIn = alertaChildElement.getChildText("CodigoVerificacao", alertaChildElement.getNamespace());
								codVerifAlerta.setText(codVerifNfeIn);
								continue;
							}
							
						}
					}
					if("Erro".equals(elem.getName())){
						Element erro = new Element("Erro");
						header.addContent(erro);
						List listErroChilds = elem.getChildren();
						Iterator erroChildIter = listErroChilds.iterator();
						while(erroChildIter.hasNext()){
							
							Element erroChildElement = (Element)erroChildIter.next();
							
							if("Codigo".equals(erroChildElement.getName())){
								Element codigoErro = new Element("Codigo");
								erro.addContent(codigoErro);
								String codigoIn = elem.getChildText("Codigo", elem.getNamespace());
								codigoErro.setText(codigoIn);
								continue;
							}	
							if("Descricao".equals(erroChildElement.getName())){
								Element descricaoErro = new Element("Descricao");
								erro.addContent(descricaoErro);
								String descricaoIn = elem.getChildText("Descricao", elem.getNamespace());
								descricaoErro.setText(descricaoIn);
								continue;
							}	
							if("ChaveRPS".equals(erroChildElement.getName())){
								
								Element chaveRPSErro = new Element("ChaveRPS");
								erro.addContent(chaveRPSErro);
								
								Element inscPrestErro = new Element("InscricaoPrestador");
								chaveRPSErro.addContent(inscPrestErro);
								String inscPrestRPSIn = erroChildElement.getChildText("InscricaoPrestador", erroChildElement.getNamespace());
								inscPrestErro.setText(inscPrestRPSIn);
								

								Element serieRPSErro  = new Element("SerieRPS");
								chaveRPSErro.addContent(serieRPSErro);
								String serieRPSIn = erroChildElement.getChildText("SerieRPS", erroChildElement.getNamespace());
								serieRPSErro.setText(serieRPSIn);
								
								Element numRPSErro = new Element("NumeroRPS");
								chaveRPSErro.addContent(numRPSErro);
								String numRPSIn = erroChildElement.getChildText("NumeroRPS", erroChildElement.getNamespace());
								numRPSErro.setText(numRPSIn);
								continue;
							}
							
							if("ChaveNFe".equals(erroChildElement.getName())){
								Element chaveNFEErro = new Element("ChaveNFe");
								erro.addContent(chaveNFEErro);
								
								Element inscPrestChaveNfeErro = new Element("InscricaoPrestador");
								chaveNFEErro.addContent(inscPrestChaveNfeErro);
								String inscPrestNfeIn = erroChildElement.getChildText("InscricaoPrestador", erroChildElement.getNamespace());
								inscPrestChaveNfeErro.setText(inscPrestNfeIn);
								
								Element numNfeErro = new Element("NumeroNFe");
								chaveNFEErro.addContent(numNfeErro);
								String numNfeIn = erroChildElement.getChildText("NumeroNFe", erroChildElement.getNamespace());
								numNfeErro.setText(numNfeIn);
								
								
								Element codVerifErro = new Element("CodigoVerificacao");
								chaveNFEErro.addContent(codVerifErro);			
								String codVerifNfeIn = erroChildElement.getChildText("CodigoVerificacao", erroChildElement.getNamespace());
								codVerifErro.setText(codVerifNfeIn);
								continue;
							}
						}
						continue;
					}
				}
			
			Document jdoc = new Document(header);
			
			DOMOutputter outputter = new DOMOutputter();
			org.w3c.dom.Document docNative = outputter.output(jdoc);
			
			TransformerFactory tf=TransformerFactory.newInstance();
			Transformer transform=tf.newTransformer();
			
			transform.transform(new DOMSource(docNative), new StreamResult(out));
		
		}catch(JDOMException e){
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			
			e.printStackTrace();
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	public void setParameter(Map objparam) {
		  this.mapTrace = objparam;
		  if(objparam == null) {
			  this.mapTrace = new HashMap();
		  }
		
		
	}

}
